﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.IO;
using System.Diagnostics.CodeAnalysis;

namespace Steve.UI
{
    public static class ContentTypeExtensions
    {
        const string HandlerNameMetadataName = "Name";

        public static ActionResult Render(this IEnumerable<Lazy<ContentDataHandlerBase, IDictionary<string, object>>> imports, ContentType contentType, Content content, bool raw)
        {
            if (contentType == null) throw new ArgumentNullException("contentType");

            return ExecuteHandler(imports, contentType, h => h.Render(content, contentType, raw));
        }

        public static ActionResult Edit(this IEnumerable<Lazy<ContentDataHandlerBase, IDictionary<string, object>>> imports, ContentType contentType, Content content)
        {
            if (contentType == null) throw new ArgumentNullException("contentType");

            return ExecuteHandler(imports, contentType, h => h.Edit(content, contentType));
        }

        public static void SaveEditData(this IEnumerable<Lazy<ContentDataHandlerBase, IDictionary<string, object>>> imports, ContentType contentType, Content toUpdate)
        {
            if (contentType == null) throw new ArgumentNullException("contentType");

            ExecuteHandler(imports, contentType, h => h.SaveEditData(contentType, toUpdate));
        }

        public static string ExtractText(this IEnumerable<Lazy<ContentDataHandlerBase, IDictionary<string, object>>> imports, ContentType contentType, Content content)
        {
            if (contentType == null) throw new ArgumentNullException("contentType");

            return ExecuteHandler(imports, contentType, h => h.ExtractText(content, contentType));
        }

        private static void ExecuteHandler(this IEnumerable<Lazy<ContentDataHandlerBase, IDictionary<string, object>>> imports, ContentType contentType, Action<ContentDataHandlerBase> exec)
        {
            var handler = (from h in imports
                           where h.Metadata.ContainsKey(HandlerNameMetadataName)
                                && string.Equals((string)h.Metadata[HandlerNameMetadataName], contentType.HandlerName, StringComparison.OrdinalIgnoreCase)
                           select h).First();

            exec(handler.Value);
        }

        private static T ExecuteHandler<T>(this IEnumerable<Lazy<ContentDataHandlerBase, IDictionary<string, object>>> imports, ContentType contentType, Func<ContentDataHandlerBase, T> exec)
        {
            var handler = (from h in imports
                           where h.Metadata.ContainsKey(HandlerNameMetadataName)
                                && string.Equals((string)h.Metadata[HandlerNameMetadataName], contentType.HandlerName, StringComparison.OrdinalIgnoreCase)
                           select h).First();

            return exec(handler.Value);
        }
    }
}
